#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <string>
#include <random>
#include <chrono>
#include <sstream>//输入输出流
#include <iomanip>
#include <atomic>

int main(){
//创建机器随机数对象
    std::random_device rd;

    std::mt19937_64 generator(rd());//rd()仿函数生成随机数种子

    std::uniform_int_distribution<int> distri(0,255);//uniform_int_distribution是一个限制类


    std::stringstream ss;

    //使用str打印

    for(int i = 0; i < 8 ;i++){//循环8次生成前8byte
        ss << std::setw(2) << std::setfill('0') << std::hex <<distri(generator);
        if(i == 3 || i == 5 || i == 7){
            ss << "-";
        }
        //将生成的随机数丢给distri对象的仿函数中进行限制大小
    }

    //实现后8byte的序号
    static std::atomic<size_t> seq(1);//初始值为1
    //静态原子的保证每次 进来 在之前序号的基础上继续
    size_t num = seq.fetch_add(1);//设置 自增长
    
    //同样事在num上操作
    //生成后面的 4 - 12，生成byte，16位十六进制
    // for(int i = 0;i < 8;i++){
    //     ss << std::setw(2) << std::setfill('0') << std::hex << ((num >> (i*8)) & (0xff));
    //     //其中 (num >> (i*8) & (0xff)) 的作用是：
    //     //首先：我们需要将num值每次取出8位，也就是1byte，也就是2位16进制（4位 = 1十六进制），所以每次移动8byte，其中我们拿第一个举例：移动i == 0 的 时候就是取前8为，当为1当时后，先右移1 * 8位，就能取到后面9 ~ 16
    //     // 然后 需要 按位与& 0xff，这里好理解，通过按位与操作，只取前8位
    //     if(i == 1 ){//分成 4 - 12
    //         ss << "-";
    //     }
    // }
    //上述写法虽然也ok，但是有点反人性（得到的序号是反过来的）不好看，解决也很简单我们就将循环遍历翻过来就哈
    for(int i = 7;i >= 0;i--){
        ss << std::setw(2) << std::setfill('0') << std::hex << ((num >> (i*8)) & (0xff));
        //其中 (num >> (i*8) & (0xff)) 的作用是：
        //首先：我们需要将num值每次取出8位，也就是1byte，也就是2位16进制（4位 = 1十六进制），所以每次移动8byte，其中我们拿第一个举例：移动i == 0 的 时候就是取前8为，当为1当时后，先右移1 * 8位，就能取到后面9 ~ 16
        // 然后 需要 按位与& 0xff，这里好理解，通过按位与操作，只取8位
        if(i == 6){//分成 4 - 12
            ss << "-";
        }
    }


    std:: cout << ss.str() << std::endl;
    return 0;
}